/**
 * Global authority directive
 * Used for fine-grained control of component permissions
 * @Example v-auth="RoleEnum.TEST"
 */
import type { Directive, DirectiveBinding } from 'vue'
import { useGlobSetting } from '@/hooks/setting'
import { useUserStoreWithOut } from '/@/store/modules/user'
const globSetting = useGlobSetting()
const { urlPrefix } = globSetting
const { getRoles } = useUserStoreWithOut()

function isAuth(el: Element, binding: any) {
  const value = binding?.value
  if (!value) return

  // action权限名称
  const actions = value.split(',').map((v) => `${urlPrefix}.${v}`) // action权限名称
  const { isSuper, permissions } = getRoles // 当前角色配置
  // 如果是超级管理员或是 codes:[*] 表示不验证权限
  if (isSuper || permissions.includes('*')) return
  // 如果权限存在，不做任何操作
  if (permissions.filter((p) => actions.includes(p))?.length) return
  // 继续比对用户当前路由权限，如果不存在action权限，则尝试移除或隐藏目标元素
  el.parentNode?.removeChild(el)
}

function isDisabled(el: Element, binding: any) {
  const value = binding?.value
  if (!value) return

  // action权限名称
  const actions = value.split(',').map((v) => `${urlPrefix}.${v}`) // action权限名称
  const { isSuper, permissions } = getRoles // 当前角色配置

  // 如果是超级管理员或是 codes:[*] 表示不验证权限
  if (isSuper || permissions.includes('*')) return

  // 如果权限存在，不做任何操作
  if (permissions.filter((p) => actions.includes(p))?.length)
    return // 继续比对用户当前路由权限，如果不存在权限，阻止该元素所有的点击事件
  ;(el as any).style.pointerEvents = 'none'
}

const inserted = (el: Element, binding: DirectiveBinding<any>) => {
  isAuth(el, binding)
}

const disabledInserted = (el: Element, binding: DirectiveBinding<any>) => {
  isDisabled(el, binding)
}

/**
 * Auth 权限指令 自定义指令
 * 指令用法：
 *  - 在需要控制 auth 级别权限的组件上使用 v-auth:[method] , 如下：
 *    <i-button v-auth="'add'" >添加用户</a-button>
 *    <a-button v-auth='test1,test2'>多个权限的情况</a-button>
 *
 *  - 当前用户没有权限时，组件上使用了该指令则会被隐藏
 *  - 当后台权限跟 pro 提供的模式不同时，只需要针对这里的权限过滤进行修改即可
 */
const authDirective: Directive = {
  inserted,
}
/**
 * disabled 权限指令 自定义指令 不可交互事件
 * 指令用法：
 *  - 在需要控制 disabled 级别权限的组件上使用 v-disabled:[method] , 如下：
 *    <i-button v-disabled="'add'" >添加用户</a-button>
 *    <a-button v-disabled='test1,test2'>多个权限的情况</a-button>
 *
 *  - 当前用户没有权限时，组件上使用了该指令则会被隐藏
 *  - 当后台权限跟 pro 提供的模式不同时，只需要针对这里的权限过滤进行修改即可
 */
const authDisabledDirective: Directive = {
  inserted: disabledInserted,
}

export function setupPermissionDirective(app: any) {
  app.directive('auth', authDirective)
  app.directive('disabled', authDisabledDirective)
}

export default authDirective
export { authDisabledDirective }
